/*
File: flexi-background.js

Author:
	Michael Bester <http://kimili.com>

About: Version
	2.0

Description:
	Javascript to set up full-screen flexible backgrounds in all widely used browsers.

License:
	Copyright 2010, Michael Bester.
	Released under the MIT license <http://opensource.org/licenses/mit-license.php>
*/

(function(){
	
	/**
		CONFIGURATION:
		Define the size of our background image
	*/
	var bgImageSize = {
		width	: 1200,
		height	: 750
	};
	
	/*	END CONFIGURATION */
	
	/**
		Detect support for CSS background-size. No need for any more javascript if background-size is supported.
		Property detection adapted from the most excellent Modernizr <http://modernizr.com>
	*/
	if ((function(){
		var el 		= document.createElement('div'),
			bs 		= 'backgroundSize',
			ubs		= bs.charAt(0).toUpperCase() + bs.substr(1),
			props	= [bs, 'Webkit' + ubs, 'Moz' + ubs, 'O' + ubs];
			
		for ( var i in props ) {
			if ( el.style[props[i]] !== undefined ) {
				return true;
			}
		}
		return false;
	}())) {
		return;
	};
	
	/**
		We also want to leave IE6 and below out in the cold with this
	*/
	if ( false /*@cc_on || @_jscript_version < 5.7 @*/ ) {
		return;
	}
	
	/**
		If we've gotten here, we don't have background-size support,
		so we'll have to mimic it with Javascript.
		Let's set up some variables
	*/
	var elBody,
		imageID		= 'expando',
		tallClass	= 'tall',
		wideClass	= 'wide',
		elBgImage, elWrapper, img, url, imgAR,
	
		/**
			Since we're not relying on a library, we'll need some utility functions
			First, basic cross browser event adders
		*/
		addEvent = function(el, evnt, func) {
			if (el.addEventListener) {
				el.addEventListener(evnt, func, false);
			} else if (el.attachEvent) {
				return el.attachEvent("on" + evnt, func);
			} else {
				el['on' + evnt] = func;
			}
		},
	
		domLoaded = function(callback) {
			/* Internet Explorer */
			/*@cc_on
			@if (@_win32 || @_win64)
			document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
			document.getElementById('ieScriptLoad').onreadystatechange = function() {
				if (this.readyState == 'complete') {
					callback();
				}
			};
			@end @*/
			/* Mozilla, Chrome, Opera */
			if (document.addEventListener) {
				document.addEventListener('DOMContentLoaded', callback, false);
			}
			/* Safari, iCab, Konqueror */
			if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
				var DOMLoadTimer = setInterval(function () {
					if (/loaded|complete/i.test(document.readyState)) {
						callback();
						clearInterval(DOMLoadTimer);
					}
				}, 10);
			}
		},
	
		/**
		 	Next, a way to properly get the computed style of an element
			Courtesy of Robert Nyman - http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/
		*/
		getStyle = function(el, css){
			var strValue = "";
			if (document.defaultView && document.defaultView.getComputedStyle){
				strValue = document.defaultView.getComputedStyle(el, "").getPropertyValue(css);
			}
			else if (el.currentStyle){
				css = css.replace(/\-(\w)/g, function (strMatch, p1){
					return p1.toUpperCase();
				});
				strValue = el.currentStyle[css];
			}
			return strValue;
		},
	
		/**
			Finally, some element class manipulation functions
		*/
		classRegex = function(cls) {
			return new RegExp('(\\s|^)'+cls+'(\\s|$)');
		},
	
		hasClass = function(el, cls) {
			return el.className.match(classRegex(cls));
		},
	
		addClass = function(el, cls) {
			if ( ! hasClass(el, cls)) {
				el.className += ' ' + cls;
			}
		},
	
		removeClass = function(el, cls) {
			if (hasClass(el, cls)) {
				el.className = el.className.replace(classRegex(cls), '');
			}
		},
	
		/*
			Now we can move on with the core functionality of Flexibackground
		*/
		initialize = function() {
		
			// No need for any of this if the screen isn't bigger than the background image
			if (screen.availWidth <= bgImageSize.width && screen.availHeight <= bgImageSize.height) {
				return;
			}
		
			// Grab elements we'll reference throughout
			elBody		= document.getElementsByTagName('body')[0];
		
			// Parse out the URL of the background image and drop out if we don't have one
			url = getStyle(elBody, 'backgroundImage').replace(/^url\(("|')?|("|')?\);?$/g, '') || false;
			if (!url || url === "none" || url === "") {
				return;
			}
		
			// Get the aspect ratio of the image
			imgAR = bgImageSize.width / bgImageSize.height;

			// Create a new image element
			elBgImage 		= document.createElement('img');
			elBgImage.src 	= url;
			elBgImage.id 	= imageID;
		
			// Create a wrapper and append the image to it.
			// The wrapper ensures we don't get scrollbars.
			elWrapper = document.createElement('div');
			elWrapper.style.overflow	= 'hidden';
			elWrapper.style.width	= '100%';
			elWrapper.style.height	= '100%';
			elWrapper.style.zIndex	= '-1';
		
			elWrapper.appendChild(elBgImage);
			elBody.appendChild(elWrapper);
		
			// Fix the wrapper into position
			elWrapper.style.position	= 'fixed';
			elWrapper.style.top		= 0;
			elWrapper.style.left		= 0;
		
			// Set up a resize listener to add/remove classes from the body 
			addEvent(window, 'resize', resizeAction);

			// Set it up by triggering a resize
			resizeAction();
		
		},
	
		/**
			Set up the action that happens on resize
		*/
		resizeAction = function() {
			var win = {
				height	: window.innerHeight || document.documentElement.clientHeight,
				width	: window.innerWidth || document.documentElement.clientWidth
			},

			// The current aspect ratio of the window
			winAR = win.width / win.height;

			// Determine if we need to show the image and whether it needs to stretch tall or wide
			if (win.width < bgImageSize.width && win.height < bgImageSize.height) {
				removeClass(elBody, wideClass);
				removeClass(elBody, tallClass);
			} else if (winAR < imgAR) {
				removeClass(elBody, wideClass);
				addClass(elBody, tallClass);
				// Center the image
				elBgImage.style.left = Math.min(((win.width - bgImageSize.width) / 2), 0);
			} else if (winAR > imgAR) {
				addClass(elBody, wideClass);
				removeClass(elBody, tallClass);
				elBgImage.style.left = 0;
			}
		};
	
	// When the document is ready, run this thing.
	domLoaded(initialize);
	
})();